#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gtk/gtk.h>
#include <dirent.h>

#include <sys/time.h>
#include <time.h>

#include "util.h"

#define PATH "/hunter_data"





int exist_directory(char* path) 
{
	if (opendir(path) == NULL)
		return 0;
	return 1;
}
int make_directory(char* basic, int year, int mon, int day, int cam_num)
{

	char basic_path[1024];
	char year_path[1024];
	char mon_path[1024];
	char day_path[1024];
	char chan_path[1024];

	strcpy(basic_path, basic);	
	sprintf(year_path, "%s/%d", basic_path, year);
	sprintf(mon_path, "%s/%d", year_path, mon);
	sprintf(day_path, "%s/%d", mon_path, day);
	sprintf(chan_path, "%s/%d", day_path, cam_num);

	if (exist_directory(day_path)) {
		mkdir(chan_path);
	} else if (exist_directory(mon_path)) {
		mkdir(day_path);
		mkdir(chan_path);

	} else if (exist_directory(year_path)) {
		mkdir(mon_path);
		mkdir(day_path);
		mkdir(chan_path);
	} else if (exist_directory(basic_path)) {
		mkdir(year_path);
		mkdir(mon_path);
		mkdir(day_path);
		mkdir(chan_path);
	} else {
		mkdir(basic_path);
		mkdir(year_path);
		mkdir(mon_path);
		mkdir(day_path);
		mkdir(chan_path);
	}
	return 1;
}

int make_index_file(char* path) 
{
	char file_name[1024];
	FILE* f;
	unsigned char buf[1];
	int i, b;

	sprintf(file_name, "%s/%s", path, "index.dat");

	if((f = fopen(file_name, "w+b")) == NULL) {
		fprintf(stderr, "Failed to file create\n");
		return -1;
	}

	buf[0] = 0x00;
	for (i = 0; i < 10800; i++)
		fwrite(buf, sizeof(unsigned char), 1, f);

	b = -1;
	for (i = 0; i < 86400; i++) 
		fwrite(&b, sizeof(int), 1, f);

	fclose(f);

	return 1;

}
char* get_file_name(int cam_num, char* index_file)
{
	struct tm *tmv;
	time_t t;
	char *path;
	int i, ret;

	path = (char*) malloc (sizeof(char)*1024);
	time(&t);
	tmv = localtime(&t);

	sprintf(path, "%s/%d/%d/%d/%d", 
			PATH, tmv->tm_year+1900, tmv->tm_mon+1, tmv->tm_mday, cam_num);

	if (!exist_directory(path)) {
		make_directory(PATH, tmv->tm_year+1900, tmv->tm_mon+1, tmv->tm_mday, cam_num);
		ret = make_index_file(path);
		if (ret == -1)
			return NULL;
	} else 
		fprintf(stderr, "file exist\n");

	sprintf(index_file, "%s/%s", path, "index.dat");
	sprintf(path, "%s/%d.mpg", path, tmv->tm_hour);

	return path;
}

int
get_year_directory(DIR *dirp, char directory[2][512], unsigned int start, unsigned int end) 
{
	struct dirent *direntp;
	int year;
	int comp_start = (start/1000000)*1000000;
	int comp_end = (end/1000000)*1000000;

	while ((direntp = readdir(dirp)) != NULL) {
		year = atoi(direntp->d_name)*1000000;
		if (strcmp(direntp->d_name, ".") && strcmp(direntp->d_name, "..") && 
								year >= comp_start && year <= comp_end) {

			sprintf(directory[1], "%s/%s", directory[0], direntp->d_name);
			return year;
		}
	}

	return -1;
}

int get_month_directory(DIR *dirp, char directory[2][512], unsigned int start, unsigned int end, int date)
{
	struct dirent *direntp;
	int mon;
	int comp_start = (start/10000)*10000;
	int comp_end = (end/10000)*10000;
	
	while ((direntp = readdir(dirp)) != NULL) {
		fprintf(stderr, "date : %d, d_name : %d\n", date, atoi(direntp->d_name));
		mon = date + atoi(direntp->d_name)*10000;
		if (strcmp(direntp->d_name, ".") && strcmp(direntp->d_name, "..") && 
							mon >= comp_start && mon <= comp_end) {
			sprintf(directory[1], "%s/%s", directory[0], direntp->d_name);
			return mon;
		}
	}
	return -1;
}
int get_day_directory(DIR *dirp, char directory[2][512], unsigned int start, unsigned int end, int date) 
{
	struct dirent *direntp;
	int day;
	int comp_start = (start/100)*100;
	int comp_end = (end/100)*100;

	while ((direntp = readdir(dirp)) != NULL) {
		day = date + atoi(direntp->d_name)*100;
		if (strcmp(direntp->d_name, ".") && strcmp(direntp->d_name, "..") && 
							day >= comp_start && day <= comp_end) {
			sprintf(directory[1], "%s/%s", directory[0], direntp->d_name);
			return day;
		}
	}

	return -1;
}
int get_chan_directory(DIR *dirp, char directory[2][512]) 
{
	struct dirent *direntp;
	
	while ((direntp = readdir(dirp)) != NULL) {
		if (strcmp(direntp->d_name, ".") && strcmp(direntp->d_name, "..")) {
			sprintf(directory[1], "%s/%s/%s", directory[0], direntp->d_name, "index.dat");
			return 1;
		}
	}
	return -1;
}
int add_file_info_of_index_file(GtkCList* file_list, char* index_file, unsigned int start, unsigned int end, int date) 
{
	FILE *f;
	int temp = 0;
	int byte_count, bit_count, len;
	int file_count = 0;
	int hour, min, sec;
	char* file_info[4];
	unsigned char buf[10800];
	int total;
	int i;

	unsigned char buf2;

	for (i = 0; i <5; i ++)
		file_info[i] = (char*)malloc(sizeof(char)*100);
	f = fopen(index_file, "rb");
	if (f == NULL) 
		return -1;

	if (date/100 == start/100) 
		temp = (start%100)*450;

	fseek(f, temp, SEEK_SET);

	len = 10800 - temp;

	if (date / 100 == end / 100)	
		len = len - (10800-(end%100)*450);

	fread(buf, 1, len, f);

	byte_count = 0;
	bit_count = 0;
	while (byte_count < len) {
		if (buf[byte_count] > 0x00) {
			while (!(buf[byte_count] & (0x80 >> bit_count))) {
				if (bit_count >= 7) 
					break;
				bit_count++;
			}

			// set date 
			sprintf(file_info[0], "%d/%d/%d", 
					date/1000000, (date%1000000)/10000, ((date%1000000)%10000)/100); 

			// set start time
			total = (temp + byte_count)*8+bit_count;
			hour = total / 3600;
			min = (total % 3600) / 60;
			sec = (total % 3600) % 60;
			sprintf(file_info[1], "%d:%d:%d", hour, min, sec);

			while (buf[byte_count] & (0x80 >> bit_count)) {
				if(bit_count >= 7) {
					byte_count++;
					bit_count = 0;
				} else
					bit_count++;
			}

			// set end time
			total = (temp + byte_count)*8+bit_count - 1;
			hour = total / 3600;
			min = (total % 3600) / 60;
			sec = (total % 3600) % 60;
			sprintf(file_info[2], "%d:%d:%d", hour, min, sec);

			// set etc
			strcpy(file_info[3], "");
			
			gtk_clist_insert(file_list, file_count++ , file_info);
		
			if ((buf2 = buf[byte_count] << bit_count) != 0x00) {
				continue;
			}

		}
		byte_count++;  
		bit_count = 0;
		
		

	}	

	return 1;
}

int
set_file_info(GtkCList* file_list, unsigned int start, unsigned int end)
{
	DIR *y_dirp, *m_dirp, *d_dirp, *c_dirp;
	char year_directory[2][512] = {"/hunter_data", ""};
	char mon_directory[2][512] = {"", ""};
	char day_directory[2][512] = {"", ""};
	char chan_directory[2][512] = {"", ""};
	int date, year, mon, day, old_date;
	int ret;

	if ((y_dirp = opendir(year_directory[0])) == NULL) {
		g_print("Error : no exist\n");
		return -1;
	}
	
	while ( (year =  get_year_directory(y_dirp, year_directory, start, end)) != -1 ) {
		strcpy(mon_directory[0], year_directory[1]);
		if ((m_dirp = opendir(mon_directory[0])) == NULL) {
			g_print("Error : no exist\n");
			return -1;
		}
		old_date = date = year;
		while ( (mon = get_month_directory(m_dirp, mon_directory, start, end, old_date)) != -1) {
			strcpy(day_directory[0], mon_directory[1]);
			if ((d_dirp = opendir(day_directory[0])) == NULL) {
				g_print("Error : no exist\n");
				return -1;
			}
			date = mon;
			while ( (day = get_day_directory(d_dirp, day_directory, start, end, date)) != -1) {
				strcpy(chan_directory[0], day_directory[1]);
				if ((c_dirp = opendir(chan_directory[0])) == NULL) {
					g_print("Error : no exist\n");
					return -1;
				}
				get_chan_directory(c_dirp, chan_directory);
				g_print("%s\n", chan_directory[1]);
				ret = add_file_info_of_index_file(file_list, chan_directory[1], start, end, day);
				if (ret == -1)
					return -1;
						
				while (closedir(c_dirp) == -1);
			} 
			while (closedir(d_dirp) == -1);
		} 
		while (closedir(m_dirp) == -1);
	} 
	while (closedir(y_dirp) == -1);

	return 1;
}
int parse_time(char *text)
{
	int start_time;
	
	start_time = atoi(strtok(text, ":")) * 3600;
	start_time += atoi(strtok(NULL, ":")) * 60;
	start_time += atoi(strtok(NULL, ":"));

	return start_time;
}
void hunter_parse_date(char *text, int* year, int* mon, int* day)
{
	
	*year = atoi(strtok(text, "/"));
	*mon = atoi(strtok(NULL, "/"));
	*day = atoi(strtok(NULL, "/"));

}

int set_play_info(struct play_info* p_info, char* path, int start_time)
{
	int i, hour;
	char chan_path[512];
	char index_file[512];

	memset(p_info->path, '\0', 512);
	strcpy(p_info->path, path);

	for (i = 0; i < 4; i++) {
		p_info->cur_pos[i] = start_time;
		p_info->state[i] = PLAY;
		sprintf(chan_path, "%s/%d", path, i);
		if (opendir(chan_path) != NULL) {
			sprintf(index_file, "%s/%s", chan_path, "index.dat");

			p_info->f[i] = fopen(index_file, "rb");
			if (p_info->f[i] == NULL) {
				fprintf(stderr, "could not open index_file\n");
				return -1;
			}

			hour = start_time / 3600;

			sprintf(p_info->file_name[i], "%s/%d.mpg", chan_path, hour);
		} else
			p_info->f[i] = NULL;
	}
	return 1;
}
int move_end_pos(FILE* f, int* pos)
{
        unsigned char temp;
        int i;

        fseek(f, (*pos)/8, SEEK_SET);
        fread(&temp, 1, 1, f);

        (*pos)++;
        i = (*pos) % 8;
        while((*pos) < 86400) {
                if (temp & 0x80 >> i) {
                        (*pos)++;
                        i++;
                        if (i >= 8) {
                                fseek(f, (*pos)/8, SEEK_SET);
                                fread(&temp, 1, 1, f);
                                i = 0;
                        }
                } else {
                        (*pos)--;
                        return 1;
                }
        }
	return -1;

}
int move_next_pos(FILE* f, int* pos)
{
        unsigned char temp;
	int old_pos = *pos;
        int i;

        fseek(f, (*pos)/8, SEEK_SET);
        fread(&temp, 1, 1, f);

        (*pos) ++;
        i = (*pos) % 8;
        while((*pos) < 86400) {
                if (!(temp & 0x80 >> i)) {
                        (*pos)++;
                        i++;
                        if (i >= 8) {
                                fseek(f, (*pos)/8, SEEK_SET);
                                fread(&temp, 1, 1, f);
                                i = 0;
                        }
                } else {
                        return 1;
                }
        }
	(*pos) = old_pos;
	return -1;

}
int move_start_pos(FILE* f, int* pos)
{
        unsigned char temp;
        int i;

        fseek(f, (*pos)/8, SEEK_SET);
        fread(&temp, 1, 1, f);

        (*pos)--;
        i = (*pos) % 8;
        while((*pos) >= 0) {
                if (temp & 0x80 >> i) {
                        (*pos)--;
                        i--;
                        if (i < 0) {
                                fseek(f, (*pos)/8, SEEK_SET);
                                fread(&temp, 1, 1, f);
                                i = 7;
                        }
                } else {
                        (*pos)++;
                        return 1;
                }
        }
	return -1;

}
int move_previous_pos(FILE* f, int* pos)
{
        unsigned char temp;
	int old_pos = *pos;
        int i;

        fseek(f, (*pos)/8, SEEK_SET);
        fread(&temp, 1, 1, f);

        (*pos)--;
        i = (*pos) % 8;
        while((*pos) >= 0) {
                if (!(temp & 0x80 >> i)) {
                        (*pos)--;
                        i--;
                        if (i < 0) {
                                fseek(f, (*pos)/8, SEEK_SET);
                                fread(&temp, 1, 1, f);
                                i = 7;
                        }
                } else {
                        return 1;
                }
        }
	(*pos) = old_pos;
	return -1;

}

